package ru.lukyanets.transmission.client.ui.controller.tabs;

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.util.Duration;
import ru.lukyanets.transmission.client.connection.ConnectionState;
import ru.lukyanets.transmission.client.connection.TransmissionService;
import ru.lukyanets.transmission.client.ui.control.PiecesIndicator;
import ru.lukyanets.transmission.client.ui.events.ChangeSelectedTorrentEvent;
import ru.lukyanets.transmission.protocol.client.exception.TransmissionException;
import ru.lukyanets.transmission.protocol.model.torrent.Torrent;

import com.google.inject.Inject;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;

/**
 * @author Sergey Lukyanets
 * @noinspection unused
 */
public class CommonController implements Initializable {
    @FXML
    public PiecesIndicator piecesIndicator;

    @Inject
    private TransmissionService transmissionService;

    @Inject
    private EventBus eventBus;

    private Timeline timeline;

    private Integer selectedId;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        timeline = new Timeline(new KeyFrame(Duration.seconds(4), (e) -> refreshInfo()));
        timeline.setCycleCount(Timeline.INDEFINITE);

        eventBus.register(new SelectedHandler());

        transmissionService.addListener((o, oldV, newState) -> Platform.runLater(() -> {
            if (!ConnectionState.CONNECTED.equals(newState)) {
                timeline.stop();
                clearInfo();
            } else {
                refreshInfo();
                timeline.play();
            }
        }));
    }

    private void refreshInfo() {
        try {
            if (selectedId != null) {
                Torrent torrent = transmissionService.getTorrent(selectedId);
                if (torrent != null) {// check post remove state
                    piecesIndicator.setBits(torrent.getPieces());
                }
            }
        } catch (TransmissionException ignore) {
        }
    }

    private void clearInfo() {
        if (selectedId != null) {
            changeSelected(null);
        }
    }

    private void changeSelected(Torrent torrent) {
        Optional<Torrent> ot = Optional.ofNullable(torrent);
        selectedId = ot.map(Torrent::getId).orElse(null);
        piecesIndicator.setCount(ot.map(Torrent::getPieceCount).orElse(0));
        piecesIndicator.setBits(ot.map(Torrent::getPieces).orElse(null));
        refreshInfo();
    }

    private class SelectedHandler {
        @Subscribe
        public void onChangeSelected(ChangeSelectedTorrentEvent event) {
            CommonController.this.changeSelected(event.getNewValue());
        }
    }
}
